﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Linq.Expressions;

namespace DataAccessLayer
{
    public interface IRepository<T> where T:class
    {

        /// <summary>
        /// Lấy tất cả ID 
        /// </summary>
        /// <param name="keys"></param>
        /// <returns></returns>
        T GetByID(params object[] keys);

        /// <summary>
        /// Trả về tất cả danh sách
        /// </summary>
        /// <returns></returns>
        IQueryable<T> GetAll();

        /// <summary>
        /// Tìm với điều kiện được định nghĩa trước
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>
        IQueryable<T> Find(Expression<Func<T, bool>> predicate);

        void InsertBatch(IEnumerable<T> entities);

        /// <summary>
        /// Thêm một đối tượng có kiểu dữ liệu là T
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        int Add(T entity);

        /// <summary>
        /// Thêm hoặc cập nhật một đối tượng entity có kiểu dữ liệu T 
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        bool InsertOrUpdate(T entity);

        /// <summary>
        /// Cập nhật đối tượng entity có kiểu dữ liệu là T
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        bool Update(T entity);

        /// <summary>
        /// Xóa đối tượng entity có kiểu dữ liệu T
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        bool Delete(T entity);

        /// <summary>
        /// Xóa đối tượng entity với biểu thức được định nghĩa trước 
        /// có kiểu dữ liệu T, kết quả trả về có kiểu dữ liệu bool
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>
        bool Delete(Expression<Func<T, bool>> predicate);

        /// <summary>
        /// Lấy tất cả dữ liệu
        /// với 2 tham gia đầu vào có kiểu dữ liệu: string và bool
        /// </summary>
        /// <param name="query"></param>
        /// <param name="StoredProcedure"></param>
        /// <returns></returns>
        object GetData(string query, bool StoredProcedure);

        /// <summary>
        /// Truy vấn một danh sách các đối tượng có kiểu dữ liệu T
        /// </summary>
        /// <param name="cmd"></param>
        /// <returns></returns>
        List<T> Query(string cmd);

        /// <summary>
        /// Truy vấn với chuổi được nhập vào có kiểu dữ liệu string
        /// và nó có kiểu dữ liệu là int 
        /// </summary>
        /// <param name="cmd"></param>
        /// <param name="x"></param>
        /// <returns></returns>
        bool Query(string cmd, int x);
        
    }
}
